<template>
  <div class="player-panel">
    <div
      class="player-style"
      ref="playerRef"
      :style="{
        height: playerHeight + 'px'
      }"
    ></div>
    <div class="danmu-panel">
      <div class="watcher">{{ onLineCount }} 人正在看,已装填 {{ danmuCount }} 条弹幕</div>
      <div id="danmu" v-show="showDanmu"></div>
      <div class="close-danmu" v-show="!showDanmu">已关闭弹幕</div>
    </div>
    <div id="play"><img :src="getLocalImage('play.png')" alt="" /></div>
  </div>
</template>

<script setup lang="ts">
import { getLocalImage } from '@/utils/utilsFun'

import Hls from 'hls.js'
import ArtPlayer from 'artplayer'
import artplayerPluginDanmuku from 'artplayer-plugin-danmuku'
import { useHomeStore } from '@/stores/home'
import { computed, inject, nextTick, onBeforeMount, onBeforeUnmount, onMounted, ref } from 'vue'
import { mitter } from '@/eventbus/eventBus'
import message from '@/utils/message'
import {
  danmuListHttpRequest,
  postDanmuHttpRequest,
  reportVideoPlayOnLineHttpRequest,
  type Danmu,
  type PostDanMuDto,
  type VideoDanmuListVO
} from '@/services/api/video'
import { useRoute } from 'vue-router'

const route = useRoute()
const homeStore = useHomeStore()

const playerRef = ref<any>('')

const emits = defineEmits(['changeWideScreen'])
const wideScreen = ref(false)

let player: any = null
//初始化视频插件
const initPlayer = () => {
  //隐藏右侧菜单
  ArtPlayer.CONTEXTMENU = false
  //自动回放功能的最大记录数，默认为10
  ArtPlayer.AUTO_PLAYBACK_MAX = 20
  //自动回放的最小记录时长 单位为秒，默认为5
  ArtPlayer.AUTO_PLAYBACK_MIN = 10
  player = new ArtPlayer({
    container: playerRef.value,
    url: ``,
    type: 'm3u8',
    customType: {
      m3u8: function (video, url, art) {
        if (Hls.isSupported()) {
          if (art.hls) art.hls.destroy()
          const hls = new Hls()
          hls.loadSource(url)
          hls.attachMedia(video)
          art.hls = hls
          art.on('destroy', () => {
            hls.destroy()
          })
        } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
          video.src = url
        } else {
          art.notice.show = '浏览器不支持该播放器'
        }
      }
    },
    theme: '#23ade5', //播放器主题颜色 用于进度条和高亮元素上
    volume: 0.7, //播放器的默认音量
    autoplay: true, //是否自动播放 假如希望默认进入页面就能自动播放视频 muted 必须为true
    autoMini: false, //当前播放器滚动到浏览器视口以外时 自动进入迷你播放模式
    fullscreen: true, //设置和获取播放器窗口全屏
    fullscreenWeb: true, //设置和获取播放器网页全屏
    setting: true,
    pip: true, //开启画中画 flip:true，
    playbackRate: true, //是否显示视频播放速度功能，会出现在 设置面板 和 右键菜单里
    flip: true, //是否显示视频翻转功能，目前只出现在 设置面板 和 右键菜单
    aspectRatio: true, //比例
    // miniProgressBar:true, //迷你进度条，只在播放器失去焦点后且正在播放时出现
    screenshot: true, //截图
    autoPlayback: true, //自动回放
    //自定义图标
    icons: {
      state: document.querySelector('#play') as HTMLElement
    },
    controls: [
      {
        name: 'wide-screen',
        position: 'right',
        html: '<span class="iconfont icon-wide-screen"></span>',
        tooltip: '宽屏模式',
        style: {
          color: '#fff',
          display: 'flex'
        },
        click: function (...args) {
          changeWideScreen()
        }
      },
      {
        name: 'narrow-screen',
        position: 'right',
        html: '<span class="iconfont icon-narrow-screen"></span>',
        tooltip: '退出宽屏',
        style: {
          color: '#fff',
          display: 'none'
        },
        click: function (...args) {
          changeWideScreen()
        }
      }
    ],
    plugins: [
      artplayerPluginDanmuku({
        mount: document.querySelector('#danmu') as HTMLDivElement,
        theme: 'light',
        emitter: true,
        danmuku: function () {
          return new Promise(async (resovle) => {
            //弹幕请求
            const danmuList = await getDanmuList()
            return resovle(danmuList as [])
          })
        },
        beforeEmit: async (danmu: PostDanMuDto) => {
          //发布弹幕请求
          const res = await postDanmu(danmu)
          //重新获取弹幕列表
          getDanmuList()
          if (!res) {
            return false
          }
          mitter.emit('danmSend')
          message.success('发布成功')
          return true
        }
      })
    ]
  })
  player.on('hover', (state: any) => {
    let display = 'none'
    if (state) {
      display = 'flex'
    }
    player.template.$bottom.style.display = display
  })

  //视频播放完成
  player.on('video:ended', (e: any) => {
    mitter.emit('playEnd')
  })
}

onMounted(() => {
  nextTick(() => {
    initPlayer()
    const height = Math.round(playerRef.value.clientWidth - 8) * 0.5625
    playerHeight.value = height
    setPlayerHeight(height)
  })

  //切换分P之后监听的事件
  mitter.on('changeP', (_fileId: any) => {
    console.log(_fileId, '分P文件ID')
    fileId.value = _fileId
    player.switch = `${homeStore.videoSourcePath}/${_fileId}/`
    player.plugins.artplayerPluginDanmuku.load()
  })
  startTime()
})

//组件卸载之前
onBeforeUnmount(() => {
  if (player) {
    player.destroy(false)
  }
  mitter.off('changeP')
  cleanTimer()
})

const playerHeight = ref(500)
const setPlayerHeight: any = inject('playerHeight')
const danmuCount = ref(0)
const fileId = ref<string>('')
//点击视频插件时触发 比如全屏、网页全屏等
const changeWideScreen = () => {
  wideScreen.value = !wideScreen.value
  if (wideScreen.value) {
    player.controls['wide-screen'].style.display = 'none'
    player.controls['narrow-screen'].style.display = 'flex'
  } else {
    player.controls['wide-screen'].style.display = 'flex'
    player.controls['narrow-screen'].style.display = 'none'
  }
  emits('changeWideScreen', wideScreen.value)
}
//弹幕列表数据
const getDanmuList = async () => {
  if (!fileId.value) {
    return []
  }
  //请求弹幕列表数据
  const res = await danmuListHttpRequest(route.params.videoId, fileId.value)
  console.log(res, '弹幕列表数据')
  mitter.emit('loadDanmu', res.data)
  danmuCount.value = res.data.length
  return res.data
}

//发送弹幕
const postDanmu = (danmu: PostDanMuDto): any => {
  console.log(danmu, '发送弹幕')

  //如果发布弹幕的时候没有登录
  if (Object.keys(homeStore.userInfo!).length == 0) {
    homeStore.setLogin(true)
    return
  }
  danmu.fileId = fileId.value
  danmu.videoId = route.params.videoId as string
  danmu.time = Math.round(danmu.time as number)
  return postDanmuHttpRequest(danmu)
    .then((res) => {
      return true
    })
    .catch((err) => {
      return false
    })
}

//采用轮询的方式统计在线观看人数
const onLineCount = ref(1)
const timer = ref<any>(null)

const startTime = () => {
  timer.value = setInterval(() => {
    reportVideoPlayOnLine()
  }, 5000)
}

//获取在线观看人数
const reportVideoPlayOnLine = async () => {
  if (!fileId.value) {
    return
  }
  const res = await reportVideoPlayOnLineHttpRequest(homeStore.deviceId, fileId.value)
  onLineCount.value = res.data
}

//卸载轮询事件
const cleanTimer = () => {
  if (timer.value != null) {
    clearInterval(timer.value)
    timer.value = null
  }
}

const videoInfoDetail: any = inject('videoInfo')
//是否展示弹幕
const showDanmu = computed(() => {
  if (!videoInfoDetail.value) return
  console.log(videoInfoDetail.value.videoInfo, '弹幕是否关闭')

  return (
    videoInfoDetail.value.videoInfo.interaction == null ||
    videoInfoDetail.value.videoInfo.interaction.indexOf('1') == -1
  )
})
onMounted(() => {})
</script>

<style lang="less" scoped>
.player-panel {
  .player-style {
    width: 100%;

    :deep(.art-video-player.art-mask-show .art-state) {
      //播放按钮
      position: absolute;
      right: 40px;
      bottom: 50px;
      .art-icon-state {
        width: 60px;
        height: 60px;
        img {
          width: 100%;
        }
      }
    }

    //改变播放器的右侧操作按钮
    :deep(.art-controls-right) {
      position: relative;
      display: block;
      width: 280px;

      .art-control {
        position: absolute;
      }

      //截屏
      .art-control-screenshot {
        left: 0;
      }

      //设置按钮
      .art-control-setting {
        left: 46px;
      }

      //画中画
      .art-control-pip {
        left: 92px;
      }

      //宽屏
      .art-control-wide-screen,
      .art-control-narrow-screen {
        left: 138px;
        .iconfont {
          font-size: 20px;
        }
      }

      //网页全屏按钮
      .art-control-fullscreenWeb {
        left: 184px;
      }

      //全屏按钮
      .art-control-fullscreen {
        left: 230px;
      }
    }
  }
  .danmu-panel {
    box-shadow: 0 2px 6px #ddd;
    height: 56px;
    border-top: none;
    background: #fff;
    display: flex;
    align-items: center;
    padding: 0px 15px;

    .watcher {
      width: 250px;
      color: var(--text2);
    }
    #danmu {
      flex: 1;
    }

    .close-danmu {
      flex: 1;
      color: var(--text2);
      text-align: center;
    }
  }

  :deep(.danmu-setting) {
    background: none !important;
    padding: 0;
    border: none;
    .inner-panel {
      width: 300px;
      height: 280px;
      position: relative;

      .inner {
        position: absolute;
        left: 0;
        top: 0;
        z-index: 99999;
        color: #fff;
      }

      .mask {
        position: absolute;
        top: 0;
        right: 0;
        left: 0;
        bottom: 0;
        background-color: #000;
        opacity: 0.6;
      }
    }
  }
}
</style>
